<!-- HTML header for doxygen 1.8.6-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<title>OpenCV: Creating a video with OpenCV</title>
<link href="../../opencv.ico" rel="shortcut icon" type="image/x-icon" />
<link href="../../tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../jquery.js"></script>
<script type="text/javascript" src="../../dynsections.js"></script>
<script type="text/javascript" src="../../tutorial-utils.js"></script>
<link href="../../search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../search/searchdata.js"></script>
<script type="text/javascript" src="../../search/search.js"></script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
//<![CDATA[
MathJax.Hub.Config(
{
  TeX: {
      Macros: {
          matTT: [ "\\[ \\left|\\begin{array}{ccc} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{array}\\right| \\]", 9],
          fork: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ \\end{array} \\right.", 4],
          forkthree: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ \\end{array} \\right.", 6],
          forkfour: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ #7 & \\mbox{#8}\\\\ \\end{array} \\right.", 8],
          vecthree: ["\\begin{bmatrix} #1\\\\ #2\\\\ #3 \\end{bmatrix}", 3],
          vecthreethree: ["\\begin{bmatrix} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{bmatrix}", 9],
          cameramatrix: ["#1 = \\begin{bmatrix} f_x & 0 & c_x\\\\ 0 & f_y & c_y\\\\ 0 & 0 & 1 \\end{bmatrix}", 1],
          distcoeffs: ["(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \\tau_x, \\tau_y]]]]) \\text{ of 4, 5, 8, 12 or 14 elements}"],
          distcoeffsfisheye: ["(k_1, k_2, k_3, k_4)"],
          hdotsfor: ["\\dots", 1],
          mathbbm: ["\\mathbb{#1}", 1],
          bordermatrix: ["\\matrix{#1}", 1]
      }
  }
}
);
//]]>
</script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js"></script>
<link href="../../doxygen.css" rel="stylesheet" type="text/css" />
<link href="../../stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<!--#include virtual="/google-search.html"-->
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="../../opencv-logo-small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">OpenCV
   &#160;<span id="projectnumber">4.5.2</span>
   </div>
   <div id="projectbrief">Open Source Computer Vision</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
</script>
<script type="text/javascript" src="../../menudata.js"></script>
<script type="text/javascript" src="../../menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('../../',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="../../d9/df8/tutorial_root.html">OpenCV Tutorials</a></li><li class="navelem"><a class="el" href="../../de/d3d/tutorial_table_of_content_app.html">Application utils (highgui, imgcodecs, videoio modules)</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Creating a video with OpenCV </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p><b>Prev Tutorial:</b> <a class="el" href="../../d5/dc4/tutorial_video_input_psnr_ssim.html">Video Input with OpenCV and similarity measurement</a></p>
<p><b>Next Tutorial:</b> <a class="el" href="../../d7/d6f/tutorial_kinect_openni.html">Using Kinect and other OpenNI compatible depth sensors</a></p>
<table class="doxtable">
<tr>
<th align="right"></th><th align="left"></th></tr>
<tr>
<td align="right">Original author </td><td align="left">Bernát Gábor </td></tr>
<tr>
<td align="right">Compatibility </td><td align="left">OpenCV &gt;= 3.0 </td></tr>
</table>
<h2>Goal </h2>
<p>Whenever you work with video feeds you may eventually want to save your image processing result in a form of a new video file. For simple video outputs you can use the OpenCV built-in <a class="el" href="../../dd/d9e/classcv_1_1VideoWriter.html">cv::VideoWriter</a> class, designed for this.</p>
<ul>
<li>How to create a video file with OpenCV</li>
<li>What type of video files you can create with OpenCV</li>
<li>How to extract a given color channel from a video</li>
</ul>
<p>As a simple demonstration I'll just extract one of the BGR color channels of an input video file into a new video. You can control the flow of the application from its console line arguments:</p>
<ul>
<li>The first argument points to the video file to work on</li>
<li>The second argument may be one of the characters: R G B. This will specify which of the channels to extract.</li>
<li>The last argument is the character Y (Yes) or N (No). If this is no, the codec used for the input video file will be the same as for the output. Otherwise, a window will pop up and allow you to select yourself the codec to use.</li>
</ul>
<p>For example, a valid command line would look like: </p><div class="fragment"><div class="line">video-write.exe video/Megamind.avi R Y</div></div><!-- fragment --> <h2>The source code </h2>
<p>You may also find the source code and these video file in the <code>samples/cpp/tutorial_code/videoio/video-write/</code> folder of the OpenCV source library or <a href="https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/videoio/video-write/video-write.cpp">download it from here</a>.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span> <span class="comment">// for standard I/O</span></div><div class="line"><span class="preprocessor">#include &lt;string&gt;</span>   <span class="comment">// for strings</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../d0/d9c/core_2include_2opencv2_2core_8hpp.html">opencv2/core.hpp</a>&gt;</span>     <span class="comment">// Basic OpenCV structures (cv::Mat)</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../dc/d3d/videoio_8hpp.html">opencv2/videoio.hpp</a>&gt;</span>  <span class="comment">// Video write</span></div><div class="line"></div><div class="line"><span class="keyword">using namespace </span><a class="code" href="../../d8/dcc/namespacestd.html">std</a>;</div><div class="line"><span class="keyword">using namespace </span><a class="code" href="../../d2/d75/namespacecv.html">cv</a>;</div><div class="line"></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">void</span> help()</div><div class="line">{</div><div class="line">    cout</div><div class="line">        &lt;&lt; <span class="stringliteral">&quot;------------------------------------------------------------------------------&quot;</span> &lt;&lt; endl</div><div class="line">        &lt;&lt; <span class="stringliteral">&quot;This program shows how to write video files.&quot;</span>                                   &lt;&lt; endl</div><div class="line">        &lt;&lt; <span class="stringliteral">&quot;You can extract the R or G or B color channel of the input video.&quot;</span>              &lt;&lt; endl</div><div class="line">        &lt;&lt; <span class="stringliteral">&quot;Usage:&quot;</span>                                                                         &lt;&lt; endl</div><div class="line">        &lt;&lt; <span class="stringliteral">&quot;./video-write &lt;input_video_name&gt; [ R | G | B] [Y | N]&quot;</span>                          &lt;&lt; endl</div><div class="line">        &lt;&lt; <span class="stringliteral">&quot;------------------------------------------------------------------------------&quot;</span> &lt;&lt; endl</div><div class="line">        &lt;&lt; endl;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[])</div><div class="line">{</div><div class="line">    help();</div><div class="line"></div><div class="line">    <span class="keywordflow">if</span> (argc != 4)</div><div class="line">    {</div><div class="line">        cout &lt;&lt; <span class="stringliteral">&quot;Not enough parameters&quot;</span> &lt;&lt; endl;</div><div class="line">        <span class="keywordflow">return</span> -1;</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keyword">const</span> <span class="keywordtype">string</span> source      = argv[1];           <span class="comment">// the source file name</span></div><div class="line">    <span class="keyword">const</span> <span class="keywordtype">bool</span> askOutputType = argv[3][0] ==<span class="charliteral">&#39;Y&#39;</span>;  <span class="comment">// If false it will use the inputs codec type</span></div><div class="line"></div><div class="line">    <a class="code" href="../../d8/dfe/classcv_1_1VideoCapture.html">VideoCapture</a> inputVideo(source);              <span class="comment">// Open input</span></div><div class="line">    <span class="keywordflow">if</span> (!inputVideo.isOpened())</div><div class="line">    {</div><div class="line">        cout  &lt;&lt; <span class="stringliteral">&quot;Could not open the input video: &quot;</span> &lt;&lt; source &lt;&lt; endl;</div><div class="line">        <span class="keywordflow">return</span> -1;</div><div class="line">    }</div><div class="line"></div><div class="line">    string::size_type pAt = source.find_last_of(<span class="charliteral">&#39;.&#39;</span>);                  <span class="comment">// Find extension point</span></div><div class="line">    <span class="keyword">const</span> <span class="keywordtype">string</span> NAME = source.substr(0, pAt) + argv[2][0] + <span class="stringliteral">&quot;.avi&quot;</span>;   <span class="comment">// Form the new name with container</span></div><div class="line">    <span class="keywordtype">int</span> ex = <span class="keyword">static_cast&lt;</span><span class="keywordtype">int</span><span class="keyword">&gt;</span>(inputVideo.get(<a class="code" href="../../d4/d15/group__videoio__flags__base.html#ggaeb8dd9c89c10a5c63c139bf7c4f5704da53e1c28d4c2ca10732af106f3bf00613">CAP_PROP_FOURCC</a>));     <span class="comment">// Get Codec Type- Int form</span></div><div class="line"></div><div class="line">    <span class="comment">// Transform from int to char via Bitwise operators</span></div><div class="line">    <span class="keywordtype">char</span> EXT[] = {(char)(ex &amp; 0XFF) , (char)((ex &amp; 0XFF00) &gt;&gt; 8),(<span class="keywordtype">char</span>)((ex &amp; 0XFF0000) &gt;&gt; 16),(char)((ex &amp; 0XFF000000) &gt;&gt; 24), 0};</div><div class="line"></div><div class="line">    <a class="code" href="../../d6/d50/classcv_1_1Size__.html">Size</a> S = <a class="code" href="../../dc/d84/group__core__basic.html#ga346f563897249351a34549137c8532a0">Size</a>((<span class="keywordtype">int</span>) inputVideo.get(<a class="code" href="../../d4/d15/group__videoio__flags__base.html#ggaeb8dd9c89c10a5c63c139bf7c4f5704dab26d2ba37086662261148e9fe93eecad">CAP_PROP_FRAME_WIDTH</a>),    <span class="comment">// Acquire input size</span></div><div class="line">                  (int) inputVideo.get(<a class="code" href="../../d4/d15/group__videoio__flags__base.html#ggaeb8dd9c89c10a5c63c139bf7c4f5704dad8b57083fd9bd58e0f94e68a54b42b7e">CAP_PROP_FRAME_HEIGHT</a>));</div><div class="line"></div><div class="line">    <a class="code" href="../../dd/d9e/classcv_1_1VideoWriter.html">VideoWriter</a> outputVideo;                                        <span class="comment">// Open the output</span></div><div class="line">    <span class="keywordflow">if</span> (askOutputType)</div><div class="line">        outputVideo.<a class="code" href="../../dd/d9e/classcv_1_1VideoWriter.html#a0901c353cd5ea05bba455317dab81130">open</a>(NAME, ex=-1, inputVideo.get(<a class="code" href="../../d4/d15/group__videoio__flags__base.html#ggaeb8dd9c89c10a5c63c139bf7c4f5704daf01bc92359d2abc9e6eeb5cbe36d9af2">CAP_PROP_FPS</a>), S, <span class="keyword">true</span>);</div><div class="line">    <span class="keywordflow">else</span></div><div class="line">        outputVideo.open(NAME, ex, inputVideo.get(<a class="code" href="../../d4/d15/group__videoio__flags__base.html#ggaeb8dd9c89c10a5c63c139bf7c4f5704daf01bc92359d2abc9e6eeb5cbe36d9af2">CAP_PROP_FPS</a>), S, <span class="keyword">true</span>);</div><div class="line"></div><div class="line">    <span class="keywordflow">if</span> (!outputVideo.isOpened())</div><div class="line">    {</div><div class="line">        cout  &lt;&lt; <span class="stringliteral">&quot;Could not open the output video for write: &quot;</span> &lt;&lt; source &lt;&lt; endl;</div><div class="line">        <span class="keywordflow">return</span> -1;</div><div class="line">    }</div><div class="line"></div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;Input frame resolution: Width=&quot;</span> &lt;&lt; S.<a class="code" href="../../d6/d50/classcv_1_1Size__.html#abfe0367b32c407ddccf5ddf92667c73d">width</a> &lt;&lt; <span class="stringliteral">&quot;  Height=&quot;</span> &lt;&lt; S.<a class="code" href="../../d6/d50/classcv_1_1Size__.html#a1d289dce6b5d8006a54f3ee0259fc545">height</a></div><div class="line">         &lt;&lt; <span class="stringliteral">&quot; of nr#: &quot;</span> &lt;&lt; inputVideo.get(<a class="code" href="../../d4/d15/group__videoio__flags__base.html#ggaeb8dd9c89c10a5c63c139bf7c4f5704dadadc646b31cfd2194794a3a80b8fa6c2">CAP_PROP_FRAME_COUNT</a>) &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;Input codec type: &quot;</span> &lt;&lt; EXT &lt;&lt; endl;</div><div class="line"></div><div class="line">    <span class="keywordtype">int</span> channel = 2; <span class="comment">// Select the channel to save</span></div><div class="line">    <span class="keywordflow">switch</span>(argv[2][0])</div><div class="line">    {</div><div class="line">    <span class="keywordflow">case</span> <span class="charliteral">&#39;R&#39;</span> : channel = 2; <span class="keywordflow">break</span>;</div><div class="line">    <span class="keywordflow">case</span> <span class="charliteral">&#39;G&#39;</span> : channel = 1; <span class="keywordflow">break</span>;</div><div class="line">    <span class="keywordflow">case</span> <span class="charliteral">&#39;B&#39;</span> : channel = 0; <span class="keywordflow">break</span>;</div><div class="line">    }</div><div class="line">    <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> src, res;</div><div class="line">    vector&lt;Mat&gt; spl;</div><div class="line"></div><div class="line">    <span class="keywordflow">for</span>(;;) <span class="comment">//Show the image captured in the window and repeat</span></div><div class="line">    {</div><div class="line">        inputVideo &gt;&gt; src;              <span class="comment">// read</span></div><div class="line">        <span class="keywordflow">if</span> (src.empty()) <span class="keywordflow">break</span>;         <span class="comment">// check if at end</span></div><div class="line"></div><div class="line">        <a class="code" href="../../d2/de8/group__core__array.html#ga0547c7fed86152d7e9d0096029c8518a">split</a>(src, spl);                <span class="comment">// process - extract only the correct channel</span></div><div class="line">        <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i =0; i &lt; 3; ++i)</div><div class="line">            <span class="keywordflow">if</span> (i != channel)</div><div class="line">                spl[i] = Mat::zeros(S, spl[0].type());</div><div class="line">       <a class="code" href="../../d2/de8/group__core__array.html#ga7d7b4d6c6ee504b30a20b1680029c7b4">merge</a>(spl, res);</div><div class="line"></div><div class="line">       <span class="comment">//outputVideo.write(res); //save or</span></div><div class="line">       outputVideo &lt;&lt; res;</div><div class="line">    }</div><div class="line"></div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;Finished writing&quot;</span> &lt;&lt; endl;</div><div class="line">    <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h2>The structure of a video </h2>
<p>For start, you should have an idea of just how a video file looks. Every video file in itself is a container. The type of the container is expressed in the files extension (for example <em>avi</em>, <em>mov</em> or <em>mkv</em>). This contains multiple elements like: video feeds, audio feeds or other tracks (like for example subtitles). How these feeds are stored is determined by the codec used for each one of them. In case of the audio tracks commonly used codecs are <em>mp3</em> or <em>aac</em>. For the video files the list is somehow longer and includes names such as <em>XVID</em>, <em>DIVX</em>, <em>H264</em> or <em>LAGS</em> (<em>Lagarith Lossless Codec</em>). The full list of codecs you may use on a system depends on just what one you have installed.</p>
<div class="image">
<img src="../../videoFileStructure.png" alt="videoFileStructure.png"/>
</div>
<p>As you can see things can get really complicated with videos. However, OpenCV is mainly a computer vision library, not a video stream, codec and write one. Therefore, the developers tried to keep this part as simple as possible. Due to this OpenCV for video containers supports only the <em>avi</em> extension, its first version. A direct limitation of this is that you cannot save a video file larger than 2 GB. Furthermore you can only create and expand a single video track inside the container. No audio or other track editing support here. Nevertheless, any video codec present on your system might work. If you encounter some of these limitations you will need to look into more specialized video writing libraries such as <em>FFmpeg</em> or codecs as <em>HuffYUV</em>, <em>CorePNG</em> and <em>LCL</em>. As an alternative, create the video track with OpenCV and expand it with sound tracks or convert it to other formats by using video manipulation programs such as <em>VirtualDub</em> or <em>AviSynth</em>.</p>
<h2>The VideoWriter class </h2>
<p>The content written here builds on the assumption you already read the <a class="el" href="../../d5/dc4/tutorial_video_input_psnr_ssim.html">Video Input with OpenCV and similarity measurement</a> tutorial and you know how to read video files. To create a video file you just need to create an instance of the <a class="el" href="../../dd/d9e/classcv_1_1VideoWriter.html">cv::VideoWriter</a> class. You can specify its properties either via parameters in the constructor or later on via the <a class="el" href="../../dd/d9e/classcv_1_1VideoWriter.html#a0901c353cd5ea05bba455317dab81130">cv::VideoWriter::open</a> function. Either way, the parameters are the same: 1. The name of the output that contains the container type in its extension. At the moment only <em>avi</em> is supported. We construct this from the input file, add to this the name of the channel to use, and finish it off with the container extension. </p><div class="fragment"><div class="line"><span class="keyword">const</span> <span class="keywordtype">string</span> source      = argv[1];            <span class="comment">// the source file name</span></div><div class="line">string::size_type pAt = source.find_last_of(<span class="charliteral">&#39;.&#39;</span>);   <span class="comment">// Find extension point</span></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">string</span> NAME = source.substr(0, pAt) + argv[2][0] + <span class="stringliteral">&quot;.avi&quot;</span>;   <span class="comment">// Form the new name with container</span></div></div><!-- fragment --><ol type="1">
<li><p class="startli">The codec to use for the video track. Now all the video codecs have a unique short name of maximum four characters. Hence, the <em>XVID</em>, <em>DIVX</em> or <em>H264</em> names. This is called a four character code. You may also ask this from an input video by using its <em>get</em> function. Because the <em>get</em> function is a general function it always returns double values. A double value is stored on 64 bits. Four characters are four bytes, meaning 32 bits. These four characters are coded in the lower 32 bits of the <em>double</em>. A simple way to throw away the upper 32 bits would be to just convert this value to <em>int</em>: </p><div class="fragment"><div class="line">VideoCapture inputVideo(source);                                <span class="comment">// Open input</span></div><div class="line"><span class="keywordtype">int</span> ex = <span class="keyword">static_cast&lt;</span><span class="keywordtype">int</span><span class="keyword">&gt;</span>(inputVideo.get(<a class="code" href="../../d4/d15/group__videoio__flags__base.html#ggaeb8dd9c89c10a5c63c139bf7c4f5704da53e1c28d4c2ca10732af106f3bf00613">CAP_PROP_FOURCC</a>));     <span class="comment">// Get Codec Type- Int form</span></div></div><!-- fragment --><p> OpenCV internally works with this integer type and expect this as its second parameter. Now to convert from the integer form to string we may use two methods: a bitwise operator and a union method. The first one extracting from an int the characters looks like (an "and" operation, some shifting and adding a 0 at the end to close the string): </p><div class="fragment"><div class="line"><span class="keywordtype">char</span> EXT[] = {ex &amp; 0XFF , (ex &amp; 0XFF00) &gt;&gt; 8,(ex &amp; 0XFF0000) &gt;&gt; 16,(ex &amp; 0XFF000000) &gt;&gt; 24, 0};</div></div><!-- fragment --><p> You can do the same thing with the <em>union</em> as: </p><div class="fragment"><div class="line"><span class="keyword">union </span>{ <span class="keywordtype">int</span> v; <span class="keywordtype">char</span> c[5];} uEx ;</div><div class="line">uEx.v = ex;                              <span class="comment">// From Int to char via union</span></div><div class="line">uEx.c[4]=<span class="charliteral">&#39;\0&#39;</span>;</div></div><!-- fragment --><p> The advantage of this is that the conversion is done automatically after assigning, while for the bitwise operator you need to do the operations whenever you change the codec type. In case you know the codecs four character code beforehand, you can use the <em>CV_FOURCC</em> macro to build the integer: </p><div class="fragment"><div class="line">CV_FOURCC(<span class="charliteral">&#39;P&#39;</span>,<span class="charliteral">&#39;I&#39;</span>,<span class="stringliteral">&#39;M,&#39;</span>1<span class="stringliteral">&#39;) // this is an MPEG1 codec from the characters to integer</span></div></div><!-- fragment --><p> If you pass for this argument minus one then a window will pop up at runtime that contains all the codec installed on your system and ask you to select the one to use:</p>
<div class="image">
<img src="../../videoCompressSelect.png" alt="videoCompressSelect.png"/>
</div>
</li>
<li>The frame per second for the output video. Again, here I keep the input videos frame per second by using the <em>get</em> function.</li>
<li>The size of the frames for the output video. Here too I keep the input videos frame size per second by using the <em>get</em> function.</li>
<li>The final argument is an optional one. By default is true and says that the output will be a colorful one (so for write you will send three channel images). To create a gray scale video pass a false parameter here.</li>
</ol>
<p>Here it is, how I use it in the sample: </p><div class="fragment"><div class="line">VideoWriter outputVideo;</div><div class="line"><a class="code" href="../../dc/d84/group__core__basic.html#ga346f563897249351a34549137c8532a0">Size</a> S = <a class="code" href="../../dc/d84/group__core__basic.html#ga346f563897249351a34549137c8532a0">Size</a>((<span class="keywordtype">int</span>) inputVideo.get(<a class="code" href="../../d4/d15/group__videoio__flags__base.html#ggaeb8dd9c89c10a5c63c139bf7c4f5704dab26d2ba37086662261148e9fe93eecad">CAP_PROP_FRAME_WIDTH</a>),    <span class="comment">//Acquire input size</span></div><div class="line">              (int) inputVideo.get(<a class="code" href="../../d4/d15/group__videoio__flags__base.html#ggaeb8dd9c89c10a5c63c139bf7c4f5704dad8b57083fd9bd58e0f94e68a54b42b7e">CAP_PROP_FRAME_HEIGHT</a>));</div><div class="line">outputVideo.open(NAME , ex, inputVideo.get(<a class="code" href="../../d4/d15/group__videoio__flags__base.html#ggaeb8dd9c89c10a5c63c139bf7c4f5704daf01bc92359d2abc9e6eeb5cbe36d9af2">CAP_PROP_FPS</a>),S, <span class="keyword">true</span>);</div></div><!-- fragment --><p> Afterwards, you use the <a class="el" href="../../dd/d9e/classcv_1_1VideoWriter.html#a9a40803e5f671968ac9efa877c984d75">cv::VideoWriter::isOpened()</a> function to find out if the open operation succeeded or not. The video file automatically closes when the <em>VideoWriter</em> object is destroyed. After you open the object with success you can send the frames of the video in a sequential order by using the <a class="el" href="../../dd/d9e/classcv_1_1VideoWriter.html#a30ebbc09c122332f62bd706b43f02a98">cv::VideoWriter::write</a> function of the class. Alternatively, you can use its overloaded operator &lt;&lt; : </p><div class="fragment"><div class="line">outputVideo.write(res);  <span class="comment">//or</span></div><div class="line">outputVideo &lt;&lt; res;</div></div><!-- fragment --><p> Extracting a color channel from an BGR image means to set to zero the BGR values of the other channels. You can either do this with image scanning operations or by using the split and merge operations. You first split the channels up into different images, set the other channels to zero images of the same size and type and finally merge them back: </p><div class="fragment"><div class="line"><a class="code" href="../../d2/de8/group__core__array.html#ga0547c7fed86152d7e9d0096029c8518a">split</a>(src, spl);                 <span class="comment">// process - extract only the correct channel</span></div><div class="line"><span class="keywordflow">for</span>( <span class="keywordtype">int</span> i =0; i &lt; 3; ++i)</div><div class="line">   <span class="keywordflow">if</span> (i != channel)</div><div class="line">      spl[i] = Mat::zeros(S, spl[0].type());</div><div class="line"><a class="code" href="../../d2/de8/group__core__array.html#ga7d7b4d6c6ee504b30a20b1680029c7b4">merge</a>(spl, res);</div></div><!-- fragment --><p> Put all this together and you'll get the upper source code, whose runtime result will show something around the idea:</p>
<div class="image">
<img src="../../resultOutputWideoWrite.png" alt="resultOutputWideoWrite.png"/>
</div>
<p>You may observe a runtime instance of this on the <a href="https://www.youtube.com/watch?v=jpBwHxsl1_0">YouTube here</a>.</p>
<div align='center'><iframe title='Video' width='560' height='349' src='https://www.youtube.com/embed/jpBwHxsl1_0?rel=0' frameborder='0' align='middle' allowfullscreen></iframe></div> </div></div><!-- contents -->
<!-- HTML footer for doxygen 1.8.6-->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Apr 2 2021 11:36:34 for OpenCV by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="../../doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
<script type="text/javascript">
//<![CDATA[
addTutorialsButtons();
//]]>
</script>
</body>
</html>
